package connectx

import (
	"fmt"
	"google.golang.org/protobuf/compiler/protogen"
	"sync"
)

// 全局缓存，用于存储服务名称转换结果
var (
	serviceNameCache sync.Map
)

type GlobalServiceName struct {
	Base                            string
	UnimplementedServiceName        string
	GrpcHttpServiceInterface        string
	ServiceDescriptorName           string
	GetServiceFuncDescriptorName    string
	NewConnectxServiceClient        string
	NewConnectxServiceHandler       string
	ClientStruct                    string
	GrpcServerInterface             string
	ServiceAdapterStructName        string
	NewServiceAdapterStructName     string
	NewServiceWithAdapterStructName string
	Server                          string
}

// ChangeServiceName 函数的定义，带缓存机制
func ChangeServiceName(service *protogen.Service) GlobalServiceName {
	// 使用服务的完整名称作为缓存键
	cacheKey := service.Desc.FullName()

	// 先尝试从缓存中获取
	if cached, ok := serviceNameCache.Load(cacheKey); ok {
		return cached.(GlobalServiceName)
	}

	// 缓存中没有，计算结果
	base := Unexport(service.GoName)
	result := GlobalServiceName{
		Base:                            base,
		UnimplementedServiceName:        fmt.Sprintf("Unimplemented%sServiceHandler", base),
		GrpcHttpServiceInterface:        fmt.Sprintf("GrpcHttp%sInterface", base),
		ServiceDescriptorName:           fmt.Sprintf("%sServiceDescriptor", service.Desc.Name()),
		GetServiceFuncDescriptorName:    fmt.Sprintf("Get%sServiceDescriptor", service.Desc.Name()),
		NewConnectxServiceClient:        fmt.Sprintf("New%sConnectxServiceClient", service.Desc.Name()),
		NewConnectxServiceHandler:       fmt.Sprintf("New%sConnectxServiceHandler", service.Desc.Name()),
		ClientStruct:                    fmt.Sprintf("%sClient", service.GoName),
		GrpcServerInterface:             fmt.Sprintf("%sServiceServer", service.GoName),
		ServiceAdapterStructName:        fmt.Sprintf("%sServiceAdapter", base),
		NewServiceAdapterStructName:     fmt.Sprintf("New%sServiceAdapter", service.GoName),
		NewServiceWithAdapterStructName: fmt.Sprintf("New%sServiceAdapterWithInterceptors", service.GoName),
		Server:                          fmt.Sprintf("%sHandler", service.GoName), //connect中的变量
	}
	// 存储到缓存中
	serviceNameCache.Store(cacheKey, result)

	return result
}

// GetServer 获取grpc_http接口名称
func GetServer(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).Server
}

// GetNewServiceWithAdapterStructName 获取grpc_http接口名称
func GetNewServiceWithAdapterStructName(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).NewServiceWithAdapterStructName
}

// GetNewServiceAdapterStructName 获取grpc_http接口名称
func GetNewServiceAdapterStructName(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).NewServiceAdapterStructName
}

// GetServiceAdapterStructName 获取grpc_http接口名称
func GetServiceAdapterStructName(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).ServiceAdapterStructName
}

// GetGrpcServerInterface 获取grpc_http接口名称
func GetGrpcServerInterface(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).GrpcServerInterface
}

// GetClientStruct 获取grpc_http接口名称
func GetClientStruct(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).ClientStruct
}

// GetNewConnectxServiceHandler 获取grpc_http接口名称
func GetNewConnectxServiceHandler(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).NewConnectxServiceHandler
}

// GetNewConnectxServiceClient 获取grpc_http接口名称
func GetNewConnectxServiceClient(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).NewConnectxServiceClient
}

// GetGetServiceFuncDescriptorName 获取grpc_http接口名称
func GetGetServiceFuncDescriptorName(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).GetServiceFuncDescriptorName
}

// GetGrpcHttpServiceInterface 获取grpc_http接口名称
func GetGrpcHttpServiceInterface(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).GrpcHttpServiceInterface
}

// GetUnimplementHandler 获取UnimplementedHandler
func GetUnimplementHandler(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).UnimplementedServiceName
}

// GetServiceDescriptorName 获取GetServiceDescriptor
func GetServiceDescriptorName(service *protogen.Service) string {
	// 直接使用ChangeServiceName函数，它内部已经处理了缓存逻辑
	return ChangeServiceName(service).ServiceDescriptorName
}
